#ifndef __SOFTUPDATEPWM_H__
#define __SOFTUPDATEPWM_H__

#include "plat/nonecopyable.h"
#include "soc/soc_timer.h"
#include "soc/soc_gpio.h"
#include "softpwmitem.h"


/// @brief 软件pwm
///        采用定时器更新模式
///        最大性能取决于MCU主频
///        采用一个定时器对应一路PWM
class SoftUpdatePwm : public NoneCopyable
{
    using PWM_FINISHED_CALLBACK = std::function<void(SoftUpdatePwm &sender)>;

public:
    explicit SoftUpdatePwm();
    virtual ~SoftUpdatePwm();

public:
    void AttachTimer(SOC_Timer *timer);
    void DettachTimer();

    void AttachGpio(const GpioPortPin &gpio, const GpioPortPin &gpioN = GpioPortPin::None());
    void DettachGpio();

    /// @brief 
    /// @param isReverse 
    /// @param normalValue 
    /// @param isSameWhenNormal
    void Config(bool isReverse, int normalValue = 0, bool isSameWhenNormal = true);
    void SetFinishedCallback(const PWM_FINISHED_CALLBACK &&func);

    void SetPeriod(int period); //一个timer，只有一个period
    int GetPeriod();
    /// @brief 必须先设置周期，才能设置duty
    /// @param duty 
    void SetDuty(int duty);
    int GetDuty();

    bool IsRunning();

    void Start();
    void Stop();

    inline uint32_t GetPrevPointUs(){return m_prevPointUs;}
    inline uint32_t GetNextPointUs(){return m_nextPointUs;}

private:
    void TimerHandler();
    void SetPeriodNoTimer(int period);
    
private:
    //使用定时器匹配中断
    SOC_Timer *m_timer = nullptr;
    PWM_FINISHED_CALLBACK m_finishedCallback = nullptr;

    SoftPwmItem m_pwmItem;
    int m_timerPeriod = 0;
    uint32_t m_prevPointUs = 0;
    uint32_t m_nextPointUs = 0;
};

#endif // __SOFTUPDATEPWM_H__
